import paramiko
import os
import time

class PytestMain:
    def __init__(self, ip, port, uname, passwd):
        """
        初始化SSH连接和SFTP客户端。

        参数:
        - ip: 服务器的IP地址。
        - port: 服务器的SSH端口号。
        - uname: 连接服务器的用户名。
        - passwd: 连接服务器的密码。
        """
        self.ip = ip
        self.port = port
        self.uname = uname
        self.passwd = passwd

        # 初始化SSH客户端并设置自动添加策略
        self.sshclt = paramiko.SSHClient()
        self.sshclt.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        # 使用提供的凭据连接SSH服务器
        self.sshclt.connect(hostname=self.ip, port=self.port, username=self.uname, password=self.passwd,
                            allow_agent=False, look_for_keys=False)

        # 初始化传输层对象并连接
        self.t = paramiko.Transport((self.ip, self.port))
        self.t.connect(username=self.uname, password=self.passwd)

        # 从传输层创建SFTP客户端
        self.sftp = paramiko.SFTPClient.from_transport(self.t)

    def get_all_local_files(self,local_dir):
        """
        递归获取当前目录下所有文件目录

        参数:
        local_dir: 当前目录的路径字符串

        返回值:
        all_files: 包含当前目录及其子目录下所有文件路径的列表
        """
        all_files = []
        # 获取当前目录下的所有文件和目录
        files = os.listdir(local_dir)
        for x in files:
            # 拼接每个文件或目录的完整路径
            filename = os.path.join(local_dir, x)
            # 如果是目录，则递归获取该目录下的所有文件和目录
            if os.path.isdir(filename):
                all_files.extend(self.get_all_local_files(filename))
            else:
                all_files.append(filename)
        return all_files

    def upload_file_path(self, local_path, remote_path):
        """
        上传本地文件或文件夹到远程服务器。

        :param local_path: 待上传的本地文件或文件夹路径。
        :param remote_path: 远程服务器上目标文件或文件夹路径。
        :return: 无返回值。
        """
        # 获取本地文件夹名，用于构造远程路径
        local_pathname = os.path.split(local_path)[-1]
        # 构造实际上传到远程服务器的路径
        real_remote_Path = remote_path + '/' + local_pathname
        # 判断远程路径是否存在，不存在则创建
        try:
            self.sftp.stat(remote_path)
        except Exception as e:
            self.sshclt.exec_command("mkdir -p %s" % remote_path)
        self.sshclt.exec_command("mkdir -p %s" % real_remote_Path)
        # 获取本地文件夹下所有文件路径
        all_files = self.get_all_local_files(local_path)
        # 遍历所有本地文件，上传至远程服务器
        for file_path in all_files:
            # 统一路径分隔符
            file_path = file_path.replace("\\", "/")
            # 获取相对于本地根文件夹的路径
            off_path_name = file_path.split(local_pathname)[-1]
            # 计算相对于远程根目录的路径
            abs_path = os.path.split(off_path_name)[0]
            # 构造远程目标文件夹路径
            reward_remote_path = real_remote_Path + abs_path
            # 判断远程目标文件夹是否存在，不存在则创建
            try:
                self.sftp.stat(reward_remote_path)
            except Exception as e:
                print(reward_remote_path)
                self.sshclt.exec_command("mkdir -p %s" % reward_remote_path)
            # 获取本地文件名，用于远程上传
            abs_file = os.path.split(file_path)[1]
            # 构造远程目标文件完整路径
            to_remote = reward_remote_path + '/' + abs_file
            time.sleep(0.1)
            self.sftp.put(file_path, to_remote)
        # 关闭SSH和SFTP连接
        self.sshclt.close()
        self.sftp.close()

    def get_path(self):
        """
        获取当前文件所在路径的函数。

        参数:
        无

        返回值:
        str: 返回当前文件的绝对路径。
        """
        return os.path.dirname(os.path.abspath(__file__))  # 获取并返回当前文件的绝对路径


    def remove_file(self, file_name):
        """
        通过SSH连接远程服务器，尝试删除指定的文件，并处理可能发生的异常。

        :param file_name: 需要删除的文件名
        :type file_name: str
        :return: 无返回值，直接执行操作并处理异常
        """
        try:
            remote_path = f"/usr/local/nginx/html/{file_name}"  # 构造远程服务器上文件的完整路径
            self.sshclt.exec_command("rm -rf %s" % remote_path)  # 使用SSH客户端执行删除命令
            print(f"删除文件 {file_name} 成功!")
        except Exception as e:
            # 这里可以自定义异常处理逻辑，例如记录日志、抛出特定错误等
            print(f"删除文件时发生错误: {e}")










